home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3.2 / Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO / packet / n17jsrc / pppcmd.c < prev    next >
C/C++ Source or Header  |  1991-06-05  |  13KB  |  591 lines

  1. /*
  2.  *  PPPCMD.C    -- PPP related user commands
  3.  *
  4.  *    This implementation of PPP is declared to be in the public domain.
  5.  *
  6.  *    Jan 91    Bill_Simpson@um.cc.umich.edu
  7.  *        Computer Systems Consulting Services
  8.  *
  9.  *    Acknowledgements and correction history may be found in PPP.C
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <time.h>
  14. #include "global.h"
  15. #include "mbuf.h"
  16. #include "iface.h"
  17. #include "pktdrvr.h"
  18. #include "ppp.h"
  19. #include "pppfsm.h"
  20. #include "pppipcp.h"
  21. #include "ppppap.h"
  22. #include "ppplcp.h"
  23. #include "cmdparse.h"
  24.  
  25. static struct iface *ppp_lookup __ARGS((char *ifname));
  26.  
  27. static int doppp_quick        __ARGS((int argc, char *argv[], void *p));
  28. static int doppp_trace        __ARGS((int argc, char *argv[], void *p));
  29.  
  30. static void genstat        __ARGS((struct ppp_s *ppp_p));
  31. static void lcpstat        __ARGS((struct fsm_s *fsm_p));
  32. static void papstat        __ARGS((struct fsm_s *fsm_p));
  33. static void ipcpstat        __ARGS((struct fsm_s *fsm_p));
  34.  
  35. static int dotry_nak        __ARGS((int argc, char *argv[], void *p));
  36. static int dotry_req        __ARGS((int argc, char *argv[], void *p));
  37. static int dotry_terminate    __ARGS((int argc, char *argv[], void *p));
  38.  
  39. static char *uptime        __ARGS((long first, long second));
  40.  
  41.  
  42. /* "ppp" subcommands */
  43. static struct cmds Pppcmds[] = {
  44.     "ipcp",        doppp_ipcp,    0,    0,    NULLCHAR,
  45.     "lcp",        doppp_lcp,    0,    0,    NULLCHAR,
  46.     "pap",        doppp_pap,    0,    0,    NULLCHAR,
  47.     "quick",    doppp_quick,    0,    0,    NULLCHAR,
  48.     "trace",    doppp_trace,    0,    0,    NULLCHAR,
  49.     NULLCHAR,
  50. };
  51.  
  52. /* "ppp <iface> <ncp> try" subcommands */
  53. static struct cmds PppTrycmds[] = {
  54.     "configure",    dotry_req,    0,    0,    NULLCHAR,
  55.     "failure",    dotry_nak,    0,    0,    NULLCHAR,
  56.     "terminate",    dotry_terminate,    0,    0,    NULLCHAR,
  57.     NULLCHAR,
  58. };
  59.  
  60. static char *PPPStatus[] = {
  61.     "Physical Line Down",
  62.     "Link Control Phase",
  63.     "Authentication Phase",
  64.     "Ready for traffic",
  65.     "Termination Phase"
  66. };
  67.  
  68. static char *NCPStatus[] = {
  69.     "Closed",
  70.     "Listen -- waiting for remote host to attempt open",
  71.     "Starting configuration exchange",
  72.     "Remote host accepted our request; waiting for remote request",
  73.     "We accepted remote request; waiting for reply to our request",
  74.     "Open",
  75.     "Terminate request sent to remote host"
  76. };
  77.  
  78. int PPPtrace;
  79.  
  80.  
  81. /****************************************************************************/
  82.  
  83. static struct iface *
  84. ppp_lookup(ifname)
  85. char *ifname;
  86. {
  87.     register struct iface *ifp;
  88.  
  89.     if ((ifp = if_lookup(ifname)) == NULLIF) {
  90.         tprintf("%s: Interface unknown\n",ifname);
  91.         return(NULLIF);
  92.     }
  93.     if (ifp->type != CL_PPP) {
  94.         tprintf("%s: not a PPP interface\n",ifp->name);
  95.         return(NULLIF);
  96.     }
  97.     return(ifp);
  98. }
  99.  
  100. /****************************************************************************/
  101.  
  102. int
  103. doppp_commands(argc,argv,p)
  104. int argc;
  105. char *argv[];
  106. void *p;
  107. {
  108.     register struct iface *ifp;
  109.  
  110.     if (argc < 2) {
  111.         tprintf( "ppp <iface> required\n" );
  112.         return -1;
  113.     }
  114.     if ((ifp = ppp_lookup(argv[1])) == NULLIF)
  115.         return -1;
  116.  
  117.     if (argc == 2 )
  118.         return ppp_status( ifp );
  119.  
  120.     return subcmd(Pppcmds, argc - 1, &argv[1], ifp);
  121. }
  122.  
  123.  
  124. /* Close connection on PPP interface */
  125. int
  126. doppp_close(argc,argv,p)
  127. int argc;
  128. char *argv[];
  129. void *p;
  130. {
  131.     register struct fsm_s *fsm_p = p;
  132.  
  133.     fsm_p->flags &= ~(FSM_ACTIVE | FSM_PASSIVE);
  134.  
  135.     fsm_close( fsm_p );
  136.     return 0;
  137. }
  138.  
  139.  
  140. int
  141. doppp_passive(argc,argv,p)
  142. int argc;
  143. char *argv[];
  144. void *p;
  145. {
  146.     register struct fsm_s *fsm_p = p;
  147.  
  148.     fsm_p->flags &= ~FSM_ACTIVE;
  149.     fsm_p->flags |= FSM_PASSIVE;
  150.  
  151.     fsm_start(fsm_p);
  152.     return 0;
  153. }
  154.  
  155.  
  156. int
  157. doppp_active(argc,argv,p)
  158. int argc;
  159. char *argv[];
  160. void *p;
  161. {
  162.     register struct fsm_s *fsm_p = p;
  163.  
  164.     fsm_p->flags &= ~FSM_PASSIVE;
  165.     fsm_p->flags |= FSM_ACTIVE;
  166.  
  167.     if ( fsm_p->state < fsmLISTEN ) {
  168.         fsm_p->state = fsmLISTEN;
  169.     }
  170.     return 0;
  171. }
  172.  
  173.  
  174. static int
  175. doppp_quick(argc,argv,p)
  176. int argc;
  177. char *argv[];
  178. void *p;
  179. {
  180.     register struct iface *ifp = p;
  181.     register struct ppp_s *ppp_p = ifp->extension;
  182.     struct lcp_s *lcp_p = ppp_p->fsm[Lcp].pdv;
  183.     struct ipcp_s *ipcp_p = ppp_p->fsm[IPcp].pdv;
  184.  
  185.     lcp_p->local.want.accm = 0L;
  186.     lcp_p->local.want.negotiate |= LCP_N_ACCM;
  187.     lcp_p->local.want.magic_number = Clock | 0x80000000L;
  188.     lcp_p->local.want.negotiate |= LCP_N_MAGIC;
  189.     lcp_p->local.want.negotiate |= LCP_N_ACFC;
  190.     lcp_p->local.want.negotiate |= LCP_N_PFC;
  191.  
  192.     ipcp_p->local.want.compression = PPP_COMPR_PROTOCOL;
  193.     ipcp_p->local.want.slots = 16;
  194.     ipcp_p->local.want.slot_compress = 1;
  195.     ipcp_p->local.want.negotiate |= IPCP_N_COMPRESS;
  196.     doppp_active( 0, NULL, &(ppp_p->fsm[IPcp]) );
  197.  
  198.     return 0;
  199. }
  200.  
  201.  
  202. /****************************************************************************/
  203.  
  204. int
  205. ppp_discard(ifp,bp)
  206. struct iface *ifp;
  207. struct mbuf *bp;
  208. {
  209.     struct ppp_s *ppp_p = ifp->extension;
  210.  
  211.     return fsm_send(&(ppp_p->fsm[Lcp]), DISCARD_REQ, 0, bp);
  212. }
  213.  
  214. int
  215. ppp_echo(ifp,bp)
  216. struct iface *ifp;
  217. struct mbuf *bp;
  218. {
  219.     struct ppp_s *ppp_p = ifp->extension;
  220.  
  221.     return fsm_send(&(ppp_p->fsm[Lcp]), ECHO_REQ, 0, bp);
  222. }
  223.  
  224. /****************************************************************************/
  225.  
  226. int
  227. ppp_status(ifp)
  228. struct iface *ifp;
  229. {
  230.     register struct ppp_s *ppp_p = ifp->extension;
  231.  
  232.     genstat(ppp_p);
  233.     if ( ppp_p->fsm[Lcp].pdv != NULL )
  234.         lcpstat(&(ppp_p->fsm[Lcp]));
  235.     if ( ppp_p->fsm[Pap].pdv != NULL )
  236.         papstat(&(ppp_p->fsm[Pap]));
  237.     if ( ppp_p->fsm[IPcp].pdv != NULL )
  238.         ipcpstat(&(ppp_p->fsm[IPcp]));
  239.     return 0;
  240. }
  241.  
  242.  
  243. static void
  244. genstat(ppp_p)
  245. register struct ppp_s *ppp_p;
  246. {
  247.  
  248.     tprintf("%s",
  249.         ppp_p->iface->name,
  250.         PPPStatus[ppp_p->phase]);
  251.  
  252.     if (ppp_p->phase == pppREADY) {
  253.         tprintf("\t(open for %s)",
  254.             uptime(ppp_p->upsince,time(0L)));
  255.     }
  256.     tprintf("\n");
  257.  
  258.     tprintf("    In"
  259.         "\t%10ld Pkts,%10ld Flag,%6d Err,%6d ChksumErr\n",
  260.         ppp_p->InRxPacketCount,
  261.         ppp_p->InOpenFlag,
  262.         ppp_p->InError,
  263.         ppp_p->InChecksum);
  264.     tprintf("\t%10ld Ip,  %6d Lcp,%6d Pap,%6d IPcp,%6d Unknown\n",
  265.         ppp_p->InIP,
  266.         ppp_p->InNCP[Lcp],
  267.         ppp_p->InNCP[Pap],
  268.         ppp_p->InNCP[IPcp],
  269.         ppp_p->InUnknown);
  270.     tprintf("    Out"
  271.         "\t%10ld Pkts,%10ld Flag,%6d Err\n",
  272.         ppp_p->OutTxPacketCount,
  273.         ppp_p->OutOpenFlag,
  274.         ppp_p->OutError);
  275.     tprintf("\t%10ld Ip,  %6d Lcp,%6d Pap,%6d IPcp\n",
  276.         ppp_p->OutIP,
  277.         ppp_p->OutNCP[Lcp],
  278.         ppp_p->OutNCP[Pap],
  279.         ppp_p->OutNCP[IPcp]);
  280. }
  281.  
  282.  
  283. static void
  284. lcpstat(fsm_p)
  285. struct fsm_s *fsm_p;
  286. {
  287.     struct lcp_s *lcp_p = fsm_p->pdv;
  288.     struct lcp_value_s *localp = &(lcp_p->local.work);
  289.     struct lcp_value_s *remotep = &(lcp_p->remote.work);
  290.  
  291.     tprintf("LCP %s\n",
  292.         NCPStatus[fsm_p->state]);
  293.  
  294.     tprintf("\t\tMRU\tACCM\t\tAP\tPFC ACFC Magic\n");
  295.  
  296.     tprintf("\tLocal:\t");
  297.  
  298.     if ( localp->negotiate & LCP_N_MRU ) {
  299.         tprintf( "%4d\t", localp->mru );
  300.     } else {
  301.         tprintf( "default\t" );
  302.     }
  303.     if ( localp->negotiate & LCP_N_ACCM ) {
  304.         tprintf( "0x%08lx\t", localp->accm );
  305.     } else {
  306.         tprintf( "default\t\t" );
  307.     }
  308.  
  309.     if ( localp->negotiate & LCP_N_AUTHENT ) {
  310.         switch ( localp->authentication ) {
  311.         case PPP_PAP_PROTOCOL:
  312.             tprintf("Pap\t");
  313.             break;
  314.         default:
  315.             tprintf("0x%04x\t", localp->authentication);
  316.             break;
  317.         };
  318.     } else {
  319.         tprintf("None\t");
  320.     }
  321.  
  322.     tprintf((localp->negotiate & LCP_N_PFC) ? "Yes " : "No  ");
  323.     tprintf((localp->negotiate & LCP_N_ACFC) ? "Yes " : "No  ");
  324.  
  325.     if ( localp->magic_number != 0L ) {
  326.         tprintf( " 0x%08lx\n", localp->magic_number );
  327.     } else {
  328.         tprintf( " unused\n" );
  329.     }
  330.  
  331.     tprintf("\tRemote:\t");
  332.  
  333.     if ( remotep->negotiate & LCP_N_MRU ) {
  334.         tprintf( "%4d\t", remotep->mru );
  335.     } else {
  336.         tprintf( "default\t" );
  337.     }
  338.     if ( remotep->negotiate & LCP_N_ACCM ) {
  339.         tprintf( "0x%08lx\t", remotep->accm );
  340.     } else {
  341.         tprintf( "default\t\t" );
  342.     }
  343.  
  344.     if ( remotep->negotiate & LCP_N_AUTHENT ) {
  345.         switch ( remotep->authentication ) {
  346.         case PPP_PAP_PROTOCOL:
  347.             tprintf("Pap\t");
  348.             break;
  349.         default:
  350.             tprintf("0x%04x\t", remotep->authentication);
  351.             break;
  352.         };
  353.     } else {
  354.         tprintf("None\t");
  355.     }
  356.  
  357.     tprintf((remotep->negotiate & LCP_N_PFC) ? "Yes " : "No  ");
  358.     tprintf((remotep->negotiate & LCP_N_ACFC) ? "Yes " : "No  ");
  359.  
  360.     if ( remotep->negotiate & LCP_N_MAGIC ) {
  361.         tprintf( " 0x%08lx\n", remotep->magic_number );
  362.     } else {
  363.         tprintf( " unused\n" );
  364.     }
  365. }
  366.  
  367.  
  368. static void
  369. papstat(fsm_p)
  370. struct fsm_s *fsm_p;
  371. {
  372.     struct pap_s *pap_p = fsm_p->pdv;
  373.  
  374.     tprintf("PAP %s\n",
  375.         NCPStatus[fsm_p->state]);
  376.  
  377.     tprintf( "\tMessage: '%s'\n", (pap_p->message == NULL) ?
  378.         "none" : pap_p->message );
  379. }
  380.  
  381.  
  382. static void
  383. ipcpstat(fsm_p)
  384. struct fsm_s *fsm_p;
  385. {
  386.     struct ipcp_s *ipcp_p = fsm_p->pdv;
  387.     struct ipcp_value_s *localp = &(ipcp_p->local.work);
  388.     struct ipcp_value_s *remotep = &(ipcp_p->remote.work);
  389.  
  390.     tprintf("IPCP %s\n",
  391.         NCPStatus[fsm_p->state]);
  392.     tprintf("\tlocal IP address: %s",
  393.         inet_ntoa(localp->address));
  394.     tprintf("\tremote IP address: %s\n",
  395.         inet_ntoa(localp->other));
  396.  
  397.     if (localp->negotiate & IPCP_N_COMPRESS) {
  398.         tprintf("    In\tTCP header compression enabled:"
  399.             " slots = %d, flag = 0x%02x\n",
  400.             localp->slots,
  401.             localp->slot_compress);
  402.         slhc_i_status(ipcp_p->slhcp);
  403.     }
  404.  
  405.     if (remotep->negotiate & IPCP_N_COMPRESS) {
  406.         tprintf("    Out\tTCP header compression enabled:"
  407.             " slots = %d, flag = 0x%02x\n",
  408.             remotep->slots,
  409.             remotep->slot_compress);
  410.         slhc_o_status(ipcp_p->slhcp);
  411.     }
  412. }
  413.  
  414.  
  415. /****************************************************************************/
  416. /* Set timeout interval when waiting for response from remote peer */
  417. int
  418. doppp_timeout(argc,argv,p)
  419. int argc;
  420. char *argv[];
  421. void *p;
  422. {
  423.     struct fsm_s *fsm_p = p;
  424.     struct timer *t = &(fsm_p->timer);
  425.  
  426.     if (argc < 2) {
  427.         tprintf("%d\n",dur_timer(t)/1000L);
  428.     } else {
  429.         int x = (int)strtol( argv[1], NULLCHARP, 0 );
  430.  
  431.         if (x <= 0) {
  432.             tprintf("Timeout value %s (%d) must be > 0\n",
  433.                 argv[1], x);
  434.             return -1;
  435.         } else {
  436.             set_timer(t, x * 1000L);
  437.         }
  438.     }
  439.     return 0;
  440. }
  441.  
  442.  
  443. int
  444. doppp_try(argc,argv,p)
  445. int argc;
  446. char *argv[];
  447. void *p;
  448. {
  449.     return subcmd(PppTrycmds, argc, argv, p);
  450. }
  451.  
  452.  
  453. static int
  454. dotry_nak(argc,argv,p)
  455. int argc;
  456. char *argv[];
  457. void *p;
  458. {
  459.     struct fsm_s *fsm_p = p;
  460.  
  461.     if (argc < 2) {
  462.         tprintf("%d\n",fsm_p->try_nak);
  463.     } else {
  464.         int x = (int)strtol( argv[1], NULLCHARP, 0 );
  465.  
  466.         if (x <= 0) {
  467.             tprintf("Value %s (%d) must be > 0\n",
  468.                 argv[1], x);
  469.             return -1;
  470.         } else {
  471.             fsm_p->try_nak = x;
  472.         }
  473.     }
  474.     return 0;
  475. }
  476.  
  477.  
  478. static int
  479. dotry_req(argc,argv,p)
  480. int argc;
  481. char *argv[];
  482. void *p;
  483. {
  484.     struct fsm_s *fsm_p = p;
  485.  
  486.     if (argc < 2) {
  487.         tprintf("%d\n",fsm_p->try_req);
  488.     } else {
  489.         int x = (int)strtol( argv[1], NULLCHARP, 0 );
  490.  
  491.         if (x <= 0) {
  492.             tprintf("Value %s (%d) must be > 0\n",
  493.                 argv[1], x);
  494.             return -1;
  495.         } else {
  496.             fsm_p->try_req = x;
  497.         }
  498.     }
  499.     return 0;
  500. }
  501.  
  502.  
  503. static int
  504. dotry_terminate(argc,argv,p)
  505. int argc;
  506. char *argv[];
  507. void *p;
  508. {
  509.     struct fsm_s *fsm_p = p;
  510.  
  511.     if (argc < 2) {
  512.         tprintf("%d\n",fsm_p->try_terminate);
  513.     } else {
  514.         int x = (int)strtol( argv[1], NULLCHARP, 0 );
  515.  
  516.         if (x <= 0) {
  517.             tprintf("Value %s (%d) must be > 0\n",
  518.                 argv[1], x);
  519.             return -1;
  520.         } else {
  521.             fsm_p->try_terminate = x;
  522.         }
  523.     }
  524.     return 0;
  525. }
  526.  
  527.  
  528. static int
  529. doppp_trace(argc,argv,p)
  530. int argc;
  531. char *argv[];
  532. void *p;
  533. {
  534.     register struct iface *ifp = p;
  535.     register struct ppp_s *ppp_p = ifp->extension;
  536.     int tracing = ppp_p->trace;
  537.     int result = setint(&tracing,"PPP tracing",argc,argv);
  538.  
  539.     ppp_p->trace = tracing;
  540.     return result;
  541. }
  542.  
  543.  
  544. /****************************************************************************/
  545. /* Break a time differential, measured in seconds, into weeks, days      */
  546. /* hours, minutes, and seconds. Store ASCII description in static buffer */
  547. #define SECS_MIN    60L
  548. #define SECS_HR        3600L
  549. #define SECS_DAY    86400L
  550. #define SECS_WEEK    604800L
  551.  
  552. static char utbuf[128];
  553.  
  554. static char *
  555. uptime(first, second)
  556. long first;
  557. long second;
  558. {
  559.     int found = 0;
  560.     long diff;
  561.     long part;
  562.  
  563.     utbuf[0] = '\0';
  564.     diff = second - first;
  565.     if ((diff > SECS_DAY)||(found)) {
  566.         part = diff / SECS_DAY;
  567.         sprintf(&(utbuf[strlen(utbuf)]),
  568.             "%ld day%s ",part,((part==1)?",":"s,"));
  569.         diff -= (part * SECS_DAY);
  570.         found = 100;
  571.     }
  572.     if ((diff > SECS_HR)||(found)) {
  573.         part = diff / SECS_HR;
  574.         sprintf(&(utbuf[strlen(utbuf)]),
  575.             "%ld hr%s ",part,((part==1)?",":"s,"));
  576.         diff -= (part * SECS_HR);
  577.         ++found;
  578.     }
  579.     if ((diff > SECS_MIN)||(found)) {
  580.         part = diff / SECS_MIN;
  581.         sprintf(&(utbuf[strlen(utbuf)]),"%ld mi%s",part,
  582.             ((found < 100)?"n, ":"n"));
  583.         diff -= (part * SECS_MIN);
  584.     }
  585.     if (found < 100)
  586.         sprintf(&(utbuf[strlen(utbuf)]),"%ld sec",diff);
  587.     return(utbuf);
  588. }
  589.  
  590.  
  591.